/**
 * @className DateUtil
 * @description 时间工具类
 * @author stydm
 * @date 2020/7/7 8:36
 */

package com.jiufengxinxi.ts.common.utils;

import com.jiufengxinxi.ts.common.constants.Constants;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.temporal.TemporalAccessor;
import java.util.*;

public class DateUtil {
    private static ThreadLocal<SimpleDateFormat> threadLocal1 = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
            dateFormat.setCalendar(new GregorianCalendar(new SimpleTimeZone(0, "GMT")));
            return dateFormat;
        }
    };
    private static ThreadLocal<SimpleDateFormatGetter> threadLocal = new ThreadLocal<SimpleDateFormatGetter>() {
        @Override
        protected SimpleDateFormatGetter initialValue() {
            return new SimpleDateFormatGetter();
        }

    };


    public static String format(Date date) {
        return threadLocal.get().getByFormat(Constants.FORMAT_yyyy_MM_dd_HH_mm_ss_SSS).format(date);
    }

    /**
     * 转换到mongo所对应日期
     *
     * @param date
     * @return
     */
    public static String formatUTC(Date date) {
        return threadLocal1.get().format(date);
    }

    public static String formatDay(Date date) {
        return threadLocal.get().getByFormat(Constants.FORMAT_yyyyMMdd).format(date);
    }

    public static String format(Date date, String format) {
        return threadLocal.get().getByFormat(format).format(date);
    }

    public static Date parse(String value, String format) throws ParseException {
        return threadLocal.get().getByFormat(format).parse(value);
    }

    public static Date parse(String value) throws ParseException {
        return threadLocal.get().getByFormat(Constants.FORMAT_yyyy_MM_dd_HH_mm_ss_SSS).parse(value);
    }

    public static Date getStartTime(Date date) {
        Calendar todayStart = Calendar.getInstance();
        if (null != date) {
            todayStart.setTime(date);
        }
        todayStart.set(Calendar.HOUR_OF_DAY, 0);
        todayStart.set(Calendar.MINUTE, 0);
        todayStart.set(Calendar.SECOND, 0);
        todayStart.set(Calendar.MILLISECOND, 0);
        return todayStart.getTime();
    }

    /**
     * @param date 将分钟后的秒毫秒至0
     * @return
     */
    public static Date getStartTimeByMinute(Date date) {
        Calendar todayStart = Calendar.getInstance();
        if (null != date) {
            todayStart.setTime(date);
        }
        todayStart.set(Calendar.SECOND, 0);
        todayStart.set(Calendar.MILLISECOND, 0);
        return todayStart.getTime();
    }

    /**
     * @param date
     * @return
     */
    public static Date getHourStartTime(Date date) {
        Calendar todayStart = Calendar.getInstance();
        if (null != date) {
            todayStart.setTime(date);
        }
        todayStart.set(Calendar.MINUTE, 0);
        todayStart.set(Calendar.SECOND, 0);
        todayStart.set(Calendar.MILLISECOND, 0);
        return todayStart.getTime();
    }

    public static Date getEndTime(Date date) {
        Calendar todayEnd = Calendar.getInstance();
        if (null != date) {
            todayEnd.setTime(date);
        }
        todayEnd.set(Calendar.HOUR_OF_DAY, 23);
        todayEnd.set(Calendar.MINUTE, 59);
        todayEnd.set(Calendar.SECOND, 59);
        todayEnd.set(Calendar.MILLISECOND, 000);
        return todayEnd.getTime();
    }

    public static Date getHourEndTime(Date date) {
        Calendar todayEnd = Calendar.getInstance();
        if (null != date) {
            todayEnd.setTime(date);
        }
        todayEnd.set(Calendar.MINUTE, 59);
        todayEnd.set(Calendar.SECOND, 59);
        todayEnd.set(Calendar.MILLISECOND, 999);
        return todayEnd.getTime();
    }

    public static boolean isHourTwoFive(Date date){
        Calendar cal = Calendar.getInstance();
        if (null != date) {
            cal.setTime(date);
        }
        return cal.get(Calendar.HOUR_OF_DAY)==2||cal.get(Calendar.HOUR_OF_DAY)==3||cal.get(Calendar.HOUR_OF_DAY)==4;
    }

    /**
     *
     */
    public static class SimpleDateFormatGetter {
        private Map<String, SimpleDateFormat> map = new HashMap();

        public SimpleDateFormat getByFormat(String _format) {
            if (_format == null) {
                return null;
            }
            SimpleDateFormat sdf = map.get(_format);
            if (sdf == null) {
                sdf = new SimpleDateFormat(_format);
                map.put(_format, sdf);
            }
            return sdf;
        }
    }

    /**
     * 获取当前的分析日期(分析前一天，用-隔开日期)
     */
    public static String getDateStrSplit() {
        Calendar now = Calendar.getInstance();
        int y = now.get(Calendar.YEAR);
        int m = (now.get(Calendar.MONTH) + 1);
        int d = now.get(Calendar.DAY_OF_MONTH);
        String date_str_split = "";
        if (m < 10) {
            if (d < 10) {
                date_str_split = y + "-0" + m + "-0" + d;
            } else {
                date_str_split = y + "-0" + m + "-" + d;
            }
        } else {
            if (d < 10) {
                date_str_split = y + "-" + m + "-0" + d;
            } else {
                date_str_split = y + "-" + m + "-" + d;
            }
        }
        return date_str_split;
    }

    /**
     * @param pre
     * @param type (0 ：天；1：小时；2 ： 分钟)
     * @return
     */

    public static Date getTime(int type, int pre) {
        Calendar calendar = Calendar.getInstance();
        if (type == 0) {
            calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) - pre);
        } else if (type == 1) {
            calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) - pre);
        } else if (type == 2) {
            calendar.set(Calendar.MINUTE, calendar.get(Calendar.MINUTE) - pre);
        }
        return calendar.getTime();
    }

    /**
     * 获取某月最大多少天
     *
     * @param date
     * @return
     */
    public static Integer getMaximum(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int maxDate = calendar.getMaximum(Calendar.DAY_OF_MONTH);
        return maxDate;
    }

    /**
     * @param pre
     * @param type (0 ：天；1：小时；2 ： 分钟)
     * @param pre  N(type)
     * @return
     */
    public static Date getTime(Date date, int type, int pre) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        if (type == 0) {
            calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) - pre);
        } else if (type == 1) {
            calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) - pre);
        } else if (type == 2) {
            calendar.set(Calendar.MINUTE, calendar.get(Calendar.MINUTE) - pre);
        }
        return calendar.getTime();
    }


    /**
     * 获取当前的分析日期(分析前一天，不用-隔开日期)
     */
    public static String getDateStrNoSplit() {
        Calendar now = Calendar.getInstance();
        int y = now.get(Calendar.YEAR);
        int m = (now.get(Calendar.MONTH) + 1);
        int d = now.get(Calendar.DAY_OF_MONTH);
        String date_str = "";
        if (m < 10) {
            if (d < 10) {
                date_str = y + "-0" + m + "-0" + d;
            } else {
                date_str = y + "-0" + m + "-" + d;
            }
        } else {
            if (d < 10) {
                date_str = y + "-" + m + "-0" + d;
            } else {
                date_str = y + "-" + m + "-" + d;
            }
        }
        return date_str;
    }

    /**
     * D_M
     * 0取前一天
     * 1 获取前一个月
     *
     * @param analyse_date
     * @param D_M
     * @return
     */
    public static String getBeforeOneDate(Date analyse_date, int D_M, String formatStr) {
        return getBeforeNDate(analyse_date, D_M, 1, formatStr);
    }

    /**
     * @param analyse_date:某天
     * @param D_M：0取前一天，1     获取前一个月 ,2  获取前一年
     * @param beforeNDay
     * @return
     */
    public static String getBeforeNDate(Date analyse_date, int D_M, int beforeNDay, String formatStr) {
        Calendar cl = Calendar.getInstance();
        String date = null;
        if (analyse_date == null) {
            analyse_date = new Date();
        }
        cl.setTime(analyse_date);
        if (D_M == 0) {
            cl.add(Calendar.DATE, -beforeNDay);
        } else if (D_M == 1) {
            cl.add(Calendar.MONTH, -beforeNDay);
        } else if (D_M == 2) {
            cl.add(Calendar.DAY_OF_YEAR, -beforeNDay);
        }
        date = format(cl.getTime(), formatStr);
        return date;
    }

    /**
     * 获取当前时间点前/后时间点
     *
     * @param analyse_date DATE_YYYY_MM_DD_HH
     * @param num          -1:往前一{type}，1:往后1{type}
     * @param timeUnit     0:hours,1:minuts ,2:day，3：month
     * @return
     */
    public static Date getBeforeTime(Date analyse_date, int num, Integer timeUnit) {
        Calendar cl = Calendar.getInstance();
        Date date = null;
        try {
            if (analyse_date != null) {
                cl.setTime(analyse_date);
            }
            switch (timeUnit) {
                case 0:
                    cl.add(Calendar.HOUR_OF_DAY, num);
                    break;
                case 1:
                    cl.add(Calendar.MINUTE, num);
                    break;
                case 3:
                    cl.add(Calendar.MONTH, num);
                    break;
                case 4:
                    cl.add(Calendar.SECOND, num);
                    break;
                case 2:
                default:
                    cl.add(Calendar.DAY_OF_MONTH, num);
            }
            date = cl.getTime();
        } catch (Exception e) {
            cl.add(Calendar.HOUR_OF_DAY, num);
            date = cl.getTime();
        }
        return date;
    }

    /**
     * 获取上周一
     *
     * @param analyse_date 指定日期直接返回当前日期
     * @return
     */
    public static String getLastWeekOne(String analyse_date) {
        Calendar cl = Calendar.getInstance();
        String date = null;
        try {
            if (analyse_date != null && analyse_date.trim().length() > 0) {
                cl.setTime(parse(analyse_date, Constants.FORMAT_YYYY_MM_DD));
                date = analyse_date;
            } else {
                cl.set(Calendar.DAY_OF_WEEK, 1);
                cl.add(Calendar.DATE, -6);
                date = format(cl.getTime(), Constants.FORMAT_YYYY_MM_DD);
            }
        } catch (Exception e) {
            cl.set(Calendar.DAY_OF_WEEK, 1);
            cl.add(Calendar.DATE, -6);
            date = format(cl.getTime(), Constants.FORMAT_YYYY_MM_DD);
        }
        return date;
    }

    /**
     * 上周日
     *
     * @param analyse_date
     * @return
     */
    public static String getLastWeekSeven(String analyse_date) {
        Calendar cl = Calendar.getInstance();
        String date = null;
        try {
            if (analyse_date != null && analyse_date.trim().length() > 0) {
                cl.setTime(parse(analyse_date, Constants.FORMAT_YYYY_MM_DD));
                cl.add(Calendar.DATE, 6);
                date = format(cl.getTime(), Constants.FORMAT_YYYY_MM_DD);
            } else {
                cl.set(Calendar.DAY_OF_WEEK, 1);
                cl.add(Calendar.DATE, 0);
                date = format(cl.getTime(), Constants.FORMAT_YYYY_MM_DD);
            }
        } catch (Exception e) {
            cl.set(Calendar.DAY_OF_WEEK, 1);
            cl.add(Calendar.DATE, 0);
            date = format(cl.getTime(), Constants.FORMAT_YYYY_MM_DD);
        }
        return date;
    }

    /**
     * 获取本周一
     *
     * @param analyse_date 指定日期
     * @return 返回当前日期的周一
     */
    public static String getWeekOne(Date analyse_date) {
        Calendar c = Calendar.getInstance();
        if (analyse_date != null) c.setTime(analyse_date);
        int day_of_week = c.get(Calendar.DAY_OF_WEEK) - 1;
        if (day_of_week == 0) day_of_week = 7;
        c.add(Calendar.DATE, -day_of_week + 1);
        String date = format(c.getTime(), Constants.FORMAT_YYYY_MM_DD);
        c.getFirstDayOfWeek();
        return date;
    }

    /**
     * 获取本周一(如果当年的时间是第一周的日期，取到的日期可能是上一年的日期)
     *
     * @param analyse_date 指定日期
     * @return 返回当前日期的周一
     */
    public static Date getWeekFirstDay(Date analyse_date) {
        Calendar c = Calendar.getInstance();
        c.setFirstDayOfWeek(Calendar.MONDAY);
        if (analyse_date != null) {
            c.setTime(analyse_date);
        }
        c.set(Calendar.HOUR, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek());
        return c.getTime();
    }
    /**
     * 获取本周日(如果当年的时间是最后一周的日期，取到的日期可能是下一年第一周的周末的日期)
     *
     * @param analyse_date 指定日期
     * @return 返回当前日期的周一
     */
    public static Date getWeekLastDay(Date analyse_date) {
        Calendar c = Calendar.getInstance();
        c.setFirstDayOfWeek(Calendar.MONDAY);
        if (analyse_date != null) {
            c.setTime(analyse_date);
        }
        c.setFirstDayOfWeek(Calendar.MONDAY);
        c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek() + 6);
        c.set(Calendar.HOUR, 23);
        c.set(Calendar.MINUTE, 59);
        c.set(Calendar.SECOND, 59);
        return c.getTime();
    }

    /**
     * 本周日
     *
     * @param analyse_date 指定日期
     * @return 返回当前日期的周日
     */
    public static String getWeekSeven(Date analyse_date) {
        Calendar c = Calendar.getInstance();
        if (analyse_date != null) c.setTime(analyse_date);
        int day_of_week = c.get(Calendar.DAY_OF_WEEK) - 1;
        if (day_of_week == 0) day_of_week = 7;
        c.add(Calendar.DATE, -day_of_week + 7);
        String date = format(c.getTime(), Constants.FORMAT_YYYY_MM_DD);
        return date;
    }

    /**
     * 取本月第一天
     *
     * @param analyse_date 指定日期
     * @return 返回指定日期当月第一天
     */
    public static Date getMonthOne(Date analyse_date) {
        Calendar calendar = Calendar.getInstance();
        if (analyse_date != null) calendar.setTime(analyse_date);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND,0);
        return calendar.getTime();
    }

    /**
     * 取本月第一天
     *
     * @param analyse_date 指定日期
     * @return 返回指定日期当月第一天 yyyyMMdd表示
     */
    public static Integer getMonthOneInt(Date analyse_date) {
        Calendar calendar = Calendar.getInstance();
        if (analyse_date != null) calendar.setTime(analyse_date);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND,0);
        return Integer.parseInt(format(calendar.getTime(), Constants.FORMAT_yyyyMMdd));
    }

    /**
     * 取上个月第一天
     */
    public static String getLastMonthOne(Date analyse_date) {
        Calendar calendar = Calendar.getInstance();
        if (analyse_date != null) calendar.setTime(analyse_date);
        calendar.add(Calendar.MONTH, -1);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        String date = format(calendar.getTime(), Constants.FORMAT_YYYY_MM_DD);
        return date;
    }

    /**
     * 取下个月第一天
     */
    public static String nextMonthFirstDate() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.add(Calendar.MONTH, 1);
        String date = format(calendar.getTime(), Constants.FORMAT_YYYY_MM_DD);
        return date;
    }

    public static Date nextMonthFirstDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.add(Calendar.MONTH, 1);

        return calendar.getTime();
    }

    /**
     * 取上个月最后一天
     *
     * @return
     */
    public static String getLastMonthLastDay(Date analyse_date) {
        Calendar calendar = Calendar.getInstance();
        if (analyse_date != null) calendar.setTime(analyse_date);
        calendar.set(Calendar.DAY_OF_MONTH, 1); //设置本月第一天
        calendar.add(Calendar.DATE, -1);
        String date = format(calendar.getTime(), Constants.FORMAT_YYYY_MM_DD);
        return date;
    }

    /**
     * 取本月最后一天
     *
     * @param analyse_date 指定日期
     * @return 返回指定日期当月最后第一天
     */
    public static Date getMonthLastDay(Date analyse_date) {
        Calendar calendar = Calendar.getInstance();
        if (analyse_date != null) calendar.setTime(analyse_date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.DAY_OF_MONTH,calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        return calendar.getTime();
    }

    /**
     * 取得上一个季度第一天
     *
     * @return
     */
    public static String getLastSeasonOne() {
        //1-3 第一季度  4-6 二季度 7-9 三季度  10-12 四季度
        Calendar c = Calendar.getInstance();
        int month = c.get(Calendar.MONTH);
        int year = c.get(Calendar.YEAR);
        if (month <= 2) {//取去年的时间
            c.set(Calendar.MONTH, 9);
            c.set(Calendar.DAY_OF_MONTH, 1);
            c.set(Calendar.YEAR, year - 1);
            String sdate = format(c.getTime(), Constants.FORMAT_YYYY_MM_DD);
            return sdate;
        } else if (month > 2 && month <= 5) {//取第一季度
            c.set(Calendar.MONTH, 0);
            c.set(Calendar.DAY_OF_MONTH, 1); //设置本月第一天
            String sdate = format(c.getTime(), Constants.FORMAT_YYYY_MM_DD);
            return sdate;
        } else if (month > 5 && month <= 8) {//第二
            c.set(Calendar.MONTH, 3);
            c.set(Calendar.DAY_OF_MONTH, 1); //设置本月第一天
            String sdate = format(c.getTime(), Constants.FORMAT_YYYY_MM_DD);
            return sdate;
        } else {//取第三季度
            c.set(Calendar.MONTH, 6);
            c.set(Calendar.DAY_OF_MONTH, 1); //设置本月第一天
            String sdate = format(c.getTime(), Constants.FORMAT_YYYY_MM_DD);
            return sdate;
        }
    }

    /**
     * 取得上一个季度最后一天
     *
     * @return
     */
    public static String getLastSeasonLastDay() {
        //1-3 第一季度  4-6 二季度 7-9 三季度  10-12 四季度
        Calendar c = Calendar.getInstance();
        int month = c.get(Calendar.MONTH);
        int year = c.get(Calendar.YEAR);
        if (month <= 2) {//取去年的时间
            c.set(Calendar.MONTH, 11);
            c.set(Calendar.DATE, 31);
            String edate = format(c.getTime(), Constants.FORMAT_YYYY_MM_DD);
            return edate;
        } else if (month > 2 && month <= 5) {//取第一季度
            c.set(Calendar.MONTH, 3);
            c.set(Calendar.DATE, -1);
            String edate = format(c.getTime(), Constants.FORMAT_YYYY_MM_DD);
            return edate;
        } else if (month > 5 && month <= 8) {//第二
            c.set(Calendar.MONTH, 5);
            c.set(Calendar.DAY_OF_MONTH, 30);
            String edate = format(c.getTime(), Constants.FORMAT_YYYY_MM_DD);
            return edate;
        } else {//取第三季度
            c.set(Calendar.MONTH, 8);
            c.set(Calendar.DAY_OF_MONTH, 30);
            String edate = format(c.getTime(), Constants.FORMAT_YYYY_MM_DD);
            return edate;
        }
    }

    /**
     * 取得本季度第一天
     *
     * @return
     */
    public static String getSeasonOne(Date analyse_date) {
        //1-3 第一季度  4-6 二季度 7-9 三季度  10-12 四季度
        Calendar c = Calendar.getInstance();
        if (analyse_date != null) c.setTime(analyse_date);
        int month = c.get(Calendar.MONTH);
        if (month > 9) {
            c.set(Calendar.MONTH, 9);
            c.set(Calendar.DAY_OF_MONTH, 1);
            String sdate = format(c.getTime(), Constants.FORMAT_YYYY_MM_DD);
            return sdate;
        } else if (month > 0 && month <= 3) {//取第一季度
            c.set(Calendar.MONTH, 0);
            c.set(Calendar.DAY_OF_MONTH, 1); //设置本月第一天
            String sdate = format(c.getTime(), Constants.FORMAT_YYYY_MM_DD);
            return sdate;
        } else if (month > 3 && month <= 6) {//第二
            c.set(Calendar.MONTH, 3);
            c.set(Calendar.DAY_OF_MONTH, 1); //设置本月第一天
            String sdate = format(c.getTime(), Constants.FORMAT_YYYY_MM_DD);
            return sdate;
        } else {//取第三季度
            c.set(Calendar.MONTH, 6);
            c.set(Calendar.DAY_OF_MONTH, 1); //设置本月第一天
            String sdate = format(c.getTime(), Constants.FORMAT_YYYY_MM_DD);
            return sdate;
        }
    }

    /**
     * 取得本季度最后一天
     *
     * @return
     */
    public static String getSeasonLastDay(Date analyse_date) {
        //1-3 第一季度  4-6 二季度 7-9 三季度  10-12 四季度
        Calendar c = Calendar.getInstance();
        if (analyse_date != null) c.setTime(analyse_date);
        int month = c.get(Calendar.MONTH);
        if (month > 9) {
            c.set(Calendar.MONTH, 11);
            c.set(Calendar.DATE, 31);
            String edate = format(c.getTime(), Constants.FORMAT_YYYY_MM_DD);
            return edate;
        } else if (month > 0 && month <= 3) {//取第一季度
            c.set(Calendar.MONTH, 3);
            c.set(Calendar.DATE, -1);
            String edate = format(c.getTime(), Constants.FORMAT_YYYY_MM_DD);
            return edate;
        } else if (month > 3 && month <= 6) {//第二
            c.set(Calendar.MONTH, 5);
            c.set(Calendar.DAY_OF_MONTH, 30);
            String edate = format(c.getTime(), Constants.FORMAT_YYYY_MM_DD);
            return edate;
        } else {//取第三季度
            c.set(Calendar.MONTH, 8);
            c.set(Calendar.DAY_OF_MONTH, 30);
            String edate = format(c.getTime(), Constants.FORMAT_YYYY_MM_DD);
            return edate;
        }
    }

    /**
     * 取当月最后一天
     *
     * @return
     */
    public static String getCurMonthLastDay() {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, 1);
        c.set(Calendar.DAY_OF_MONTH, 0);
        String edate = format(c.getTime(), Constants.FORMAT_YYYY_MM_DD);
        return edate;
    }

    /**
     * 取当月最后一天
     *
     * @return
     */
    public static String getCurMonthFirstDay() {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, 0);
        c.set(Calendar.DAY_OF_MONTH, 1);
        String edate = format(c.getTime(), Constants.FORMAT_YYYY_MM_DD);
        return edate;
    }

    /**
     * 获取年
     *
     * @param date
     * @return
     */
    public static int getYear(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.YEAR);
    }



    /**
     * 取2个时间相差多少秒
     *
     * @return
     */
    public static List<String> getBetweenDates(Date start, Date end) {
        List<String> result = new ArrayList<String>();
        Calendar tempStart = Calendar.getInstance();
        tempStart.setTime(start);
        tempStart.add(Calendar.DAY_OF_YEAR, 1);

        Calendar tempEnd = Calendar.getInstance();
        tempEnd.setTime(end);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        if (sdf.format(start).equals(sdf.format(end))) {
            result.add(sdf.format(start));
        } else {
            result.add(sdf.format(start));
            while (tempStart.before(tempEnd)) {
                result.add(sdf.format(tempStart.getTime()));
                tempStart.add(Calendar.DAY_OF_YEAR, 1);
            }
            result.add(sdf.format(end));
        }

        return result;
    }

    /**
     * 日期转换为字符串 格式自定义
     *
     * @param date
     * @param f
     * @return
     */
    public static String dateStr(Date date, String f) {
        if (date == null) {
            return "";
        }
        String str = threadLocal.get().getByFormat(f).format(date);
        return str;
    }

    /**
     * 获得当前日期
     *
     * @return
     */
    public static Date getNow() {
        Calendar cal = Calendar.getInstance();
        Date currDate = cal.getTime();
        return currDate;
    }

    /**
     * 计算两个日期之间相差的天数
     *
     * @param date1
     * @param date2
     * @return date1>date2时结果<0,  date1=date2时结果=0, date2>date1时结果>0
     */
    public static int daysBetween(Date date1, Date date2, String format) {
        DateFormat sdf = threadLocal.get().getByFormat(format);
        Calendar cal = Calendar.getInstance();
        try {
            Date d1 = sdf.parse(DateUtil.dateStr(date1, format));
            Date d2 = sdf.parse(DateUtil.dateStr(date2, format));
            cal.setTime(d1);
            long time1 = cal.getTimeInMillis();
            cal.setTime(d2);
            long time2 = cal.getTimeInMillis();
            return Integer.parseInt(String.valueOf((time2 - time1) / 86400000L));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 计算两个日期之间相差的小时数
     *
     * @param date1
     * @param date2
     * @return
     */
    public static int hoursBetween(Date date1, Date date2) {
        DateFormat sdf = threadLocal.get().getByFormat("yyyyMMdd");
        Calendar cal = Calendar.getInstance();
        try {
            Date d1 = sdf.parse(DateUtil.dateStr(date1, "yyyyMMdd"));
            Date d2 = sdf.parse(DateUtil.dateStr(date2, "yyyyMMdd"));
            cal.setTime(d1);
            long time1 = cal.getTimeInMillis();
            cal.setTime(d2);
            long time2 = cal.getTimeInMillis();
            return Integer.parseInt(String.valueOf((time2 - time1) / 3600000L));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return 0;
    }

    public static int secondBetween(Date date1, Date date2) {
        DateFormat sdf = threadLocal.get().getByFormat("yyyyMMdd HH:mm:ss");
        Calendar cal = Calendar.getInstance();
        try {
            Date d1 = sdf.parse(DateUtil.dateStr(date1, "yyyyMMdd HH:mm:ss"));
            Date d2 = sdf.parse(DateUtil.dateStr(date2, "yyyyMMdd HH:mm:ss"));
            cal.setTime(d1);
            long time1 = cal.getTimeInMillis();
            cal.setTime(d2);
            long time2 = cal.getTimeInMillis();
            long l = (time2 - time1) / 1000;
            return (int) l;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 取得当年的第几周
     *
     * @param date
     * @return
     */
    public static int getWeekOfYear(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.setFirstDayOfWeek(Calendar.MONDAY);
        return c.get(Calendar.WEEK_OF_YEAR);
    }

    /**
     * 1 第一季度 2 第二季度 3 第三季度 4 第四季度
     *
     * @param date
     * @return
     */
    public static int getSeason(Date date) {

        int season = 0;

        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int month = c.get(Calendar.MONTH);
        switch (month) {
            case Calendar.JANUARY:
            case Calendar.FEBRUARY:
            case Calendar.MARCH:
                season = 1;
                break;
            case Calendar.APRIL:
            case Calendar.MAY:
            case Calendar.JUNE:
                season = 2;
                break;
            case Calendar.JULY:
            case Calendar.AUGUST:
            case Calendar.SEPTEMBER:
                season = 3;
                break;
            case Calendar.OCTOBER:
            case Calendar.NOVEMBER:
            case Calendar.DECEMBER:
                season = 4;
                break;
            default:
                break;
        }
        return season;
    }

    /**
     * 获取季度总天数
     *
     * @param date
     * @return
     */
    public static int getSeasonDayCount(Date date) {
        int dayCount = 0;
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        switch (getSeason(date)) {
            case 1:
                calendar.set(Calendar.MONTH, Calendar.JANUARY);
                dayCount += calendar.getActualMaximum(Calendar.DATE);
                calendar.set(Calendar.MONTH, Calendar.FEBRUARY);
                dayCount += calendar.getActualMaximum(Calendar.DATE);
                calendar.set(Calendar.MONTH, Calendar.MARCH);
                dayCount += calendar.getActualMaximum(Calendar.DATE);
                break;
            case 2:
                calendar.set(Calendar.MONTH, Calendar.APRIL);
                dayCount += calendar.getActualMaximum(Calendar.DATE);
                calendar.set(Calendar.MONTH, Calendar.MAY);
                dayCount += calendar.getActualMaximum(Calendar.DATE);
                calendar.set(Calendar.MONTH, Calendar.JUNE);
                dayCount += calendar.getActualMaximum(Calendar.DATE);
                break;
            case 3:
                calendar.set(Calendar.MONTH, Calendar.JULY);
                dayCount += calendar.getActualMaximum(Calendar.DATE);
                calendar.set(Calendar.MONTH, Calendar.AUGUST);
                dayCount += calendar.getActualMaximum(Calendar.DATE);
                calendar.set(Calendar.MONTH, Calendar.SEPTEMBER);
                dayCount += calendar.getActualMaximum(Calendar.DATE);
                break;
            case 4:
                calendar.set(Calendar.MONTH, Calendar.OCTOBER);
                dayCount += calendar.getActualMaximum(Calendar.DATE);
                calendar.set(Calendar.MONTH, Calendar.NOVEMBER);
                dayCount += calendar.getActualMaximum(Calendar.DATE);
                calendar.set(Calendar.MONTH, Calendar.DECEMBER);
                dayCount += calendar.getActualMaximum(Calendar.DATE);
                break;
            default:
        }
        return dayCount;
    }

    /**
     * 是否为闰年
     *
     * @param date
     * @return
     */
    public static boolean runNian(Date date) {
        int year = getYear(date);
        if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 判断时间是否在时间段内
     *
     * @param nowTime
     * @param beginTime
     * @param endTime
     * @return
     */
    public static boolean betweenCalendar(Date nowTime, Date beginTime, Date endTime) {
        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);
        Calendar begin = Calendar.getInstance();
        begin.setTime(beginTime);
        Calendar end = Calendar.getInstance();
        end.setTime(endTime);
        return betweenCalendar(date, begin, end);
    }

    /**
     * 判断时间是否在时间段内
     *
     * @param nowCalendar
     * @param beginCalendar
     * @param endCalendar
     * @return
     */
    public static boolean betweenCalendar(Calendar nowCalendar, Calendar beginCalendar, Calendar endCalendar) {
        if (nowCalendar.after(beginCalendar) && nowCalendar.before(endCalendar)) {
            return true;
        } else if (nowCalendar.getTime().compareTo(beginCalendar.getTime()) == 0 || nowCalendar.getTime().compareTo(endCalendar.getTime()) == 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Date 转 localDateTime
     */
    public static LocalDateTime date2LocalDateTime(Date date) {
        Instant instant = date.toInstant();
        ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());
        LocalDateTime localDateTime = zdt.toLocalDateTime();
        return localDateTime;
    }
    /**
     * Date 转 localDate
     */
    public static LocalDate date2LocalDate(Date date) {
        Instant instant = date.toInstant();
        ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());
        LocalDate localDate = zdt.toLocalDate();
        return localDate;
    }

    //一天的开始
    public static Date getStartOfDay(String date) {
        LocalDate localDate = LocalDate.parse(date);
        return getStartOfDay(localDate);
    }

    public static Date getStartOfDay(Date date) {
        LocalDate localDate = date2LocalDate(date);
        return getStartOfDay(localDate);
    }


    public static Date getStartOfDay(TemporalAccessor date) {
        LocalDate localDate = LocalDate.from(date);
        return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
    }

    //一天的结束
    public static Date getEndOfDay(String date) {
        LocalDate localDate = LocalDate.parse(date);
        return getEndOfDay(localDate);
    }

    public static Date getEndOfDay(Date date) {
        LocalDate localDate = date2LocalDate(date);
        return getEndOfDay(localDate);
    }

    public static Date getEndOfDay(TemporalAccessor date) {
        LocalDate localDate = LocalDate.from(date);
        return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).plusDays(1L).minusNanos(1L).toInstant());
    }

    /**
     * 获取某月的总天数
     *
     * @param date
     * @return
     */
    public static int getMonthCount(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.getActualMaximum(Calendar.DATE);
    }

    /**
     * 获取某周的总天数
     *
     * @param date
     * @return
     */
    public static int getWeekDayCount(Date date) {
        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT+:08:00"));
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_WEEK);
    }

    public static boolean isInPauseTime(Date date,String timeDivision){
        if (timeDivision == null) return false;
        String timeDivisions[] = timeDivision.split("-");
        if (timeDivisions.length != 2) return false;
        String now = threadLocal.get().getByFormat("HH:mm").format(date);
        return now.compareTo(timeDivisions[0])>=0&&now.compareTo(timeDivisions[1])<=0;
    }


    /**
     * 根据表名，想要拼接的表名类型，得到相应的表名
     *
     * @param type
     *            1:年 tableName_2019; 2:月 tableName_1901;
     * @param tableName
     * @return
     */
    public static String getDocumentName(Integer type, String tableName,Date beforeDate) {
        switch (type) {
            case 1:
                return tableName+"_"+new SimpleDateFormat("yyyy").format(beforeDate);
            case 2:
                return tableName+"_"+new SimpleDateFormat("yyyyMMdd").format(beforeDate).substring(2,6);
        }
        return null;
    }

    /**
     * date 转 字符串日期
     * @param date  日期
     * @param format  格式：yyyy-MM-dd
     * @return sdate
     */
    public static  String  DateToString (Date date,String format ) {
        String sdate = "";
        if(date!=null&&format!=null){
            SimpleDateFormat dateFormat = new SimpleDateFormat(format);
            return sdate =dateFormat.format(date);
        }else if (date!=null){
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            return sdate =  dateFormat.format(date) ;
        }else if(format!=null){
            SimpleDateFormat dateFormat = new SimpleDateFormat(format);
            return sdate =  dateFormat.format(new Date()) ;
        }else{
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            return sdate =  dateFormat.format(new Date()) ;

        }


    }



    public static LocalDate StringToLocalDate(String dateString){
        String [] dateSplit=dateString.split(",");
        if(dateSplit.length!=3){
            return null;
        }
        int y=Integer.parseInt(dateSplit[0]);
        int h=Integer.parseInt(dateSplit[1]);
        int d=Integer.parseInt(dateSplit[2]);

        return LocalDate.of(y,h,d);
    }

    public static LocalDateTime GetDateTimeOfTimestamp(long timestamp) {
        Instant instant = Instant.ofEpochMilli(timestamp);
        ZoneId zone = ZoneId.systemDefault();
        return LocalDateTime.ofInstant(instant, zone);
    }


    public static long GetTimestampOfDateTime(LocalDateTime localDateTime) {
        ZoneId zone = ZoneId.systemDefault();
        Instant instant = localDateTime.atZone(zone).toInstant();
        return instant.toEpochMilli();
    }

    /**
     * date 转 字符串日期
     * @param localDate  日期
     * @param type  格式："d" yyhhdd "h" yyhh
     * @return String
     */
    public static String GetIntStrByType(LocalDate localDate,String type){
        String y=localDate.getYear()+"";
        String h=localDate.getMonthValue()+"";
        String d=localDate.getDayOfMonth()+"";
        if(localDate.getMonthValue()<10){
            h="0"+h;
        }
        if(localDate.getDayOfMonth()<10){
            d="0"+d;
        }
        String reStr="";
        if(type.equals("d")){
            reStr=y.substring(2,4)+h+d;
        }else if(type.equals("h")){
            reStr=y.substring(2,4)+h;
        }
        return reStr;
    }

    public static String GetSuffixStrByType(LocalDate localDate,String type){
        String y=localDate.getYear()+"";
        String h=localDate.getMonthValue()+"";
        String d=localDate.getDayOfMonth()+"";
        if(localDate.getMonthValue()<10){
            h="0"+h;
        }
        if(localDate.getDayOfMonth()<10){
            d="0"+d;
        }
        String reStr="";
        if(type.equals("d")){
            reStr=y+"_"+h+"_"+d;
        }else if(type.equals("h")){
            reStr=y+"_"+h;
        }
        return reStr;
    }

    public static int GetBetweenLocalDateTime(LocalDateTime dateTime1,LocalDateTime dateTime2){
        return Math.abs((int)((DateUtil.GetTimestampOfDateTime(dateTime1)-DateUtil.GetTimestampOfDateTime(dateTime2))/1000));
    }

    public static void main(String[] args) throws ParseException {
        Date nowDate = new Date();// DateUtil.parse("2019-03-30",
        // Constants.FORMAT_YYYY_MM_DD);
        // Calendar instance =
        // Calendar.getInstance(TimeZone.getTimeZone("GMT+:08:00"));
//		Date firstDay = DateUtil.getMonthOne(nowDate);
//		Date endDay = DateUtil.getMonthLastDay(nowDate);
//		int weekOfYear = DateUtil.getWeekOfYear(nowDate);
//		System.out.println(weekOfYear);
//
//		LocalDate date =LocalDate.now();
//        System.out.println(date.with(DayOfWeek.MONDAY));
//        System.out.println(date.with(DayOfWeek.SUNDAY));
        System.out.println(isHourTwoFive(nowDate));

        Calendar todayEnd = Calendar.getInstance();
        if (null != nowDate) {
            todayEnd.setTime(nowDate);
        }
        todayEnd.set(Calendar.HOUR_OF_DAY, 1);
        System.out.println(isHourTwoFive(todayEnd.getTime()));
        todayEnd.set(Calendar.HOUR_OF_DAY, 2);
        System.out.println(isHourTwoFive(todayEnd.getTime()));
        todayEnd.set(Calendar.HOUR_OF_DAY, 3);
        System.out.println(isHourTwoFive(todayEnd.getTime()));
        todayEnd.set(Calendar.HOUR_OF_DAY, 4);
        System.out.println(isHourTwoFive(todayEnd.getTime()));
        todayEnd.set(Calendar.HOUR_OF_DAY, 5);
        System.out.println(isHourTwoFive(todayEnd.getTime()));
        todayEnd.set(Calendar.HOUR_OF_DAY, 14);
        System.out.println(isHourTwoFive(todayEnd.getTime()));

        //String current_mon_day = DateUtil.format(nowDate, Constants.FORMAT_YYYY_MM_DD);
        //String day = current_mon_day.substring(current_mon_day.length() - 2, current_mon_day.length());
//        Date beforeTime = DateUtil.getBeforeTime(nowDate, -10, 1);
//        String tttt = DateUtil.format(nowDate, Constants.FORMAT_yyyy_MM_ddTHH_mm_ss_SSSZ);
//        String yearlast = DateUtil.getSeasonOne(new Date(System.currentTimeMillis() - 24 * 3600000 * 61));
//        int weekOfYear = DateUtil.getWeekOfYear(new Date());
//        System.out.println(weekOfYear + yearlast);
//        System.out.println("nowDate:" + DateUtil.dateStr(nowDate, Constants.FORMAT_yyyy_MM_dd_HH_mm_ss) + ",beforeTime:" + DateUtil.dateStr(beforeTime, Constants.FORMAT_yyyy_MM_dd_HH_mm_ss));
    }
}
